package com.spsa.persistencia.dao;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.spsa.excepciones.GuardarDatosException;
import com.spsa.excepciones.RecuperarDatosException;
import com.spsa.negocio.utilidades.EstadoArchivo;
import com.spsa.persistencia.entidades.EstadoInterfaz;
import com.spsa.persistencia.entidades.Interfaz;
import com.spsa.persistencia.entidades.Tienda;

@Stateless
public class EstadoInterfazDao implements Serializable {
	static final Logger logger = LogManager.getLogger(EstadoInterfazDao.class.getName());

	@PersistenceContext(unitName = "Notificacion")
	private EntityManager em;

	public void guardarOrActualizar(EstadoInterfaz estadoInterfaz) throws GuardarDatosException {
		try {
			em.merge(estadoInterfaz);
		} catch (Exception e) {
			logger.error("No se pudo guardar un Estado en la BD. " + estadoInterfaz, e);
			throw new GuardarDatosException("No se pudo guardar un Estado en la BD. " + estadoInterfaz);
		}
	}

	public List<EstadoInterfaz> obtenerEstados(Date fecha, Interfaz interfaz) throws RecuperarDatosException {
		List<EstadoInterfaz> estados;

		Query query = em
				.createQuery("SELECT e FROM EstadoInterfaz e WHERE e.descripcionInterfaz = :descripcionInterfaz "
						+ "AND e.fechaUso = :fecha and e.fechaProcesamiento = (SELECT MAX(e1.fechaProcesamiento) FROM EstadoInterfaz e1 WHERE e1.fechaUso = :fecha"
						+ " AND e1.codigoTienda = e.codigoTienda AND e1.descripcionInterfaz = :descripcionInterfaz)");

		query.setParameter("fecha", fecha);
		query.setParameter("descripcionInterfaz", interfaz.getDescripcion());

		try {
			estados = query.getResultList();
		} catch (Exception e) {
			logger.error("No se pudo recuperar la lista de Estados de la BD." + interfaz + " Fecha: " + new Date(), e);
			throw new RecuperarDatosException("No se pudo recuperar la lista de Estados de la BD." + interfaz
					+ " Fecha: " + new Date());
		}

		return estados;
	}

	public List<EstadoInterfaz> listarEstadosRojosMarcados(Date fechaInicio, Date fechaFin, Tienda tienda)
			throws RecuperarDatosException {
		List<EstadoInterfaz> estados;

		logger.info("Inicio: " + fechaInicio + " Fin: " + fechaFin + " Tienda: " + tienda.getCodigo());
		Query query = em
				.createQuery("SELECT e FROM EstadoInterfaz e WHERE e.codigoTienda = :codigoTienda "
						+ "AND e.fechaUso >= :fechaInicio AND e.fechaUso <= :fechaFin AND e.marcado = :marcado AND e.estadoArchivos <> :estadoArchivos");

		query.setParameter("fechaInicio", fechaInicio);
		query.setParameter("fechaFin", fechaFin);
		query.setParameter("codigoTienda", tienda.getCodigo());
		query.setParameter("marcado", true);
		query.setParameter("estadoArchivos", EstadoArchivo.PROCESADO);

		try {
			estados = query.getResultList();
		} catch (Exception e) {
			logger.error("No se pudo recuperar la lista de Estados de la BD por fecha y tienda." + " Fecha inicio: "
					+ fechaInicio + " Fecha fin: " + fechaFin + "Codigo tienda: + " + tienda.getCodigo(), e);
			throw new RecuperarDatosException("No se pudo recuperar la lista de Estados de la BD.");
		}

		logger.info("Se han recuperado " + estados.size() + " estados en rojo de la BD");
		return estados;
	}

	public List<EstadoInterfaz> listarEstadosRojosMarcados(Date fechaInicio, Date fechaFin, Interfaz interfaz) 
		throws RecuperarDatosException{
		List<EstadoInterfaz> estados;

		logger.info("Inicio: " + fechaInicio + " Fin: " + fechaFin + " Interfaz: " + interfaz.getDescripcion());
		Query query = em
				.createQuery("SELECT e FROM EstadoInterfaz e WHERE e.descripcionInterfaz = :descripcionInterfaz "
						+ "AND e.fechaUso >= :fechaInicio AND e.fechaUso <= :fechaFin AND e.marcado = :marcado AND e.estadoArchivos <> :estadoArchivos");

		query.setParameter("fechaInicio", fechaInicio);
		query.setParameter("fechaFin", fechaFin);
		query.setParameter("descripcionInterfaz", interfaz.getDescripcion());
		query.setParameter("marcado", true);
		query.setParameter("estadoArchivos", EstadoArchivo.PROCESADO);

		try {
			estados = query.getResultList();
		} catch (Exception e) {
			logger.error("No se pudo recuperar la lista de Estados de la BD por fecha y tienda." + " Fecha inicio: "
					+ fechaInicio + " Fecha fin: " + fechaFin + "Interfaz: + " + interfaz.getDescripcion(), e);
			throw new RecuperarDatosException("No se pudo recuperar la lista de Estados de la BD.");
		}

		logger.info("Se han recuperado " + estados.size() + " estados en rojo de la BD");
		return estados;
	}
}
